﻿using Agora.Rtc;
using HandyControl.Controls;
using HandyControl.Tools;
using HandyControl.Tools.Extension;
using MyMeeting.Common;
using MyMeeting.Dtos;
using MyMeeting.Extensions;
using MyMeeting.Service;
using MyMeeting.Views.Dialogs;
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Forms.Integration;
using System.Windows.Media;

namespace MyMeeting.ViewModels.Dialogs
{
    public class MeetDemoViewModel : BindableBase, IDialogAware
    {
        private VideoViual centerVideo;
        public WrapPanel remotePanel;
        public System.Windows.Controls.ListBox UserVisual;
        public System.Windows.Controls.Grid CenterGrid;
        public System.Windows.Controls.Panel CenterVisual;
        public string Title => "会议demo";
        public event Action<IDialogResult> RequestClose;
        private IEventAggregator eg;
        public DelegateCommand OpenVideoCommand { get; set; }
        public DelegateCommand OpAudioCommand { get; set; }
        public DelegateCommand GetJoinUsersCommand { get; set; }
        public DelegateCommand ShareScreenCommand { get; set; }
        private string btnVideoText = "视频已关闭";
        private string btnAudioText = "音频已关闭";
        private uint volume = 0;
        private Visibility userVisable = Visibility.Collapsed;
        public Visibility UserVisable { get => userVisable; set { userVisable = value; RaisePropertyChanged(); } }
        private ObservableCollection<MeetUser> onlineUsers;

        public ObservableCollection<MeetUser> OnlineUsers
        {
            get { return onlineUsers; }
            set { onlineUsers = value; RaisePropertyChanged(); }
        }

        public string BtnVideoText
        {
            get { return btnVideoText; }
            set
            {
                btnVideoText = value;
                RaisePropertyChanged();
            }
        }

        public string BtnAudioText
        {
            get { return btnAudioText; }
            set
            {
                btnAudioText = value;
                RaisePropertyChanged();
            }
        }
        public uint Volume { get => volume; set
            {
                volume = value;RaisePropertyChanged();
            } }

        
        public VideoCanvas centerCanvas { get; private set; }
        ShengGEngine MeetEngine { get => PrismManager.MeetEngine; }
        public MeetDemoViewModel(IEventAggregator eventAggregator) : base()
        {

            //  LoadedCommand = new(Loaded);
            OpenVideoCommand = new DelegateCommand(OpenVideo);
            OpAudioCommand = new DelegateCommand(OpAudio);
            GetJoinUsersCommand = new DelegateCommand(ShowJoinUsers);
            ShareScreenCommand = new DelegateCommand(OpShareScreen);
            eg = eventAggregator;
            OnlineUsers = new ObservableCollection<MeetUser>();

        }

        private void OpShareScreen()
        {
            var user = PrismManager.CurrentUser;
            if (user.isShareScreen == false)
            {
                var ret = MeetEngine.StartShareScreen();

                if (ret != null) user.isShareScreen = true;
            }
            else
            {
                var ret = MeetEngine.Rtc.StopScreenCapture();
                if (ret == 0)
                {
                    MeetEngine.DicMeetUsers[user.Id].IsOpenVideo = false;
                    MeetEngine.DicMeetUsers[user.Id].ClearBackground();

                    if(centerVideo.Uid==user.Id)
                    {
                        centerVideo.ClearBackground();
                    }
                    user.isShareScreen = false;

                }
            }
        }

        private void ShowJoinUsers()
        {
            if (this.UserVisual == null) return;
            if (this.UserVisual.IsVisible == false)
            {
                UserVisable = Visibility.Visible;
                // this.UserVisual.Visibility= System.Windows.Visibility.Visible;
                // this.UserVisual.Width = 180;
                // this.UserVisual.Visibility = System.Windows.Visibility.Visible;
                // this.CenterGrid.ColumnDefinitions[1].Width = new System.Windows.GridLength(180);
            }
            else
            {
                UserVisable = Visibility.Collapsed;
                //this.CenterVisual.Width = 1024;
                // this.UserVisual.Visibility = System.Windows.Visibility.Collapsed;
                //    this.UserVisual.Collapse();
                // this.CenterGrid.ColumnDefinitions[1].Width = new System.Windows.GridLength(0);
            }
        }

        private void UpdateOnlineUser(VideoViual ctl)
        {
            var find = OnlineUsers.ToList().Find(a => a.Id == ctl.Uid);
            if (find != null)
            {
                find.IsOpenAudio = ctl.IsOpenAudio;
                find.IsOpenVideo = ctl.IsOpenVideo;
                find.Volume = ctl.Volume;
            }
        }

        private void UpdateOnlineUserVolume(List<AudioVolumeInfo>list)
        {
            var uids = list.Select(a => a.uid);
            foreach ( var user in OnlineUsers.ToList().Where(a => uids.Contains(a.Id)))
            {
                if(user.IsOpenAudio==false)
                {
                    user.Volume = 0;
                    continue;
                }
                user.Volume = list.Find(a => a.uid == user.Id).volume;
            }
        }

        private void OpAudio()
        {
            var user = PrismManager.CurrentUser;
            if (centerVideo.Uid != user.Id) return;
            VideoViual ctl = MeetEngine.OpenLocalAudio(user.Channel, user.Id);
            if (ctl != null)
            {
                centerVideo.IsOpenAudio = ctl.IsOpenAudio;
                BtnAudioText = ctl.IsOpenAudio ? "音频已开启" : "音频已关闭";

                UpdateOnlineUser(ctl);
            }

        }

        private void OpenVideo()
        {
            var user = PrismManager.CurrentUser;
            if (centerVideo.Uid != user.Id) return;
            var ctl = MeetEngine.OpenLocalVideo(user.Channel, user.Id);

            if (ctl != null)
            {
                centerVideo.IsOpenVideo = ctl.IsOpenVideo;
                BtnVideoText = ctl.IsOpenVideo ? "视频已开启" : "视频已关闭";
                UpdateOnlineUser(ctl);
            }

        }
        public bool CanCloseDialog()
        {
            return true;
        }

        public void OnDialogClosed()
        {
            MeetEngine.LeaveChannel();
            this.ClearEvent();
        }

        private void ClearEvent()
        {
            MeetEngine.EnableRemoteVideoEvent -= EnableRemoteVideo;
            MeetEngine.EnableRemoteAudioEvent -= EnableRemoteAudio;
            MeetEngine.JoinUserEvent -= UserJoined;
            MeetEngine.LeaveUserEvent -= UserLeaved;
            this.centerVideo.ChangeCenterEvent -= CenterVideoChanged;
            MeetEngine.VolumeChangeEvent -= VolumeChanged;
        }

        public void OnDialogOpened(IDialogParameters parameters)
        {
            eg.GetEvent<PubSubEvent<MeetDemoView>>().Subscribe((a) =>
            {
                var img = a.Img_Diplay;
                this.remotePanel = a.RemotePanel;

                this.CenterVisual = a.VideoCtl;
                this.UserVisual = a.onlineUser;
                this.CenterGrid = a.CenterGrid;
                var user = PrismManager.CurrentUser;
                this.centerVideo = new VideoViual(this.remotePanel, null, user.Token, user.Channel, user.Id);
                this.centerVideo.ChangeCenterEvent += CenterVideoChanged;
                centerVideo.VerticalAlignment = VerticalAlignment.Stretch;
                centerVideo.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
                centerVideo.Width = 1024;
                centerVideo.Height = 576;
                centerVideo.SetImage();
                a.VideoCtl.Children.Add(centerVideo);

                MeetEngine.AddCenter(user.Channel, this.centerVideo);
                MeetEngine.EnableRemoteVideoEvent += EnableRemoteVideo;
                MeetEngine.EnableRemoteAudioEvent += EnableRemoteAudio;
                MeetEngine.JoinUserEvent += UserJoined;
                MeetEngine.LeaveUserEvent += UserLeaved;
                MeetEngine.VolumeChangeEvent += VolumeChanged;
                MeetEngine.JoinChannel(user.Channel, user.Token, user.Id);
            });
        }

        private void VolumeChanged(string channel, List<AudioVolumeInfo> list)
        {
            if (centerVideo.ChannelId != channel) return;
            if(centerVideo.IsOpenAudio==false)
            {
                centerVideo.Volume = 0;
            }
            foreach (var v in list)
            {
                if(v.uid==centerVideo.Uid)
                {
                    this.Volume = v.volume;

                    if(centerVideo.IsOpenAudio==false)
                    {
                        this.Volume = 0;
                    }
                }
            }
            UpdateOnlineUserVolume(list);
        }

        private void UserLeaved(VideoViual ctl)
        {
            var find = OnlineUsers.ToList().Find(a => a.Id == ctl.Uid);
            if (find != null)
            {
                this.UserVisual.Dispatcher.Invoke(() =>
                {
                    OnlineUsers.Remove(find);
                });
            }
        }

        private void UserJoined(VideoViual ctl)
        {
            var meetUser = new MeetUser();
            meetUser.Id = ctl.Uid;
            meetUser.Channel = ctl.ChannelId;
            meetUser.UserName = "用户" + ctl.Uid;
            meetUser.IsOpenVideo = ctl.IsOpenVideo;
            meetUser.IsOpenAudio = ctl.IsOpenAudio;
            this.UserVisual.Dispatcher.Invoke(() =>
            {
                OnlineUsers.Add(meetUser);
            });
        }

        private void CenterVideoChanged(VideoViual control)
        {
            BtnAudioText = centerVideo.IsOpenAudio ? "音频已开启" : "音频已关闭";
            BtnVideoText = centerVideo.IsOpenVideo ? "视频已开启" : "视频已关闭";
        }

        private void EnableRemoteAudio(VideoViual control)
        {
            if (centerVideo.Uid == control.Uid)
            {
                BtnAudioText = control.IsOpenAudio ? "音频已开启" : "音频已关闭";
                centerVideo.IsOpenAudio = control.IsOpenAudio;
            }
            UpdateOnlineUser(control);
        }

        private void EnableRemoteVideo(VideoViual control)
        {
            if (centerVideo.Uid == control.Uid)
            {
                BtnVideoText = control.IsOpenVideo ? "视频已开启" : "视频已关闭";
                centerVideo.IsOpenVideo = control.IsOpenVideo;
                centerVideo.ClearBackground();
                control.ClearBackground();
            }
            UpdateOnlineUser(control);
        }

    }
}
